package cn.itcast.redisdemo;

import io.lettuce.core.ReadFrom;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.redis.LettuceClientConfigurationBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;

@SpringBootApplication
public class RedisDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(RedisDemoApplication.class, args);
    }


    /**
     * 这个bean中配置的就是读写策略，包括四种：
     * - MASTER：从主节点读取
     * - MASTER_PREFERRED：优先从master节点读取，master不可用才读取replica
     * - REPLICA：从slave（replica）节点读取
     * - REPLICA _PREFERRED：优先从slave（replica）节点读取，所有的slave都不可用才读取master
     */
    @Bean
    public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer() {
        return new LettuceClientConfigurationBuilderCustomizer() {
            @Override
            public void customize(LettuceClientConfiguration.LettuceClientConfigurationBuilder clientConfigurationBuilder) {
                clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
            }
        };
    }

    //连接哨兵
    //Trying to get a Redis Sentinel connection for one of: [RedisURI [host='192.168.138.150', port=27001], RedisURI [host='192.168.138.150', port=27002], RedisURI [host='192.168.138.150', port=27003]]

    //Connecting to Redis Sentinel, address: RedisURI [host='192.168.138.150', port=27001]


    //订阅主节点
    //Decoded SubscriptionCommand [type=SENTINEL, output=MapOutput [output={name=mymaster, ip=192.168.138.150, port=7003, runid=953647769d77ee89974a2c917d721d9319e0f60e, flags=master, link-pending-commands=0, link-refcount=1, last-ping-sent=0, last-ok-ping-reply=888, last-ping-reply=888, down-after-milliseconds=5000, info-refresh=9261, role-reported=master, role-reported-time=1414884, config-epoch=1, num-slaves=2, num-other-sentinels=2, quorum=2, failover-timeout=60000, parallel-syncs=1}, error='null'], commandType=io.lettuce.core.protocol.Command], empty stack: true

    //订阅从节点
    //Decoded SubscriptionCommand [type=SENTINEL, output=ListOfMapsOutput [output=[{name=192.168.138.150:7001, ip=192.168.138.150, port=7001, runid=eb13f0fc80958665d442cbbbfb7e2d7cba1cb445, flags=slave, link-pending-commands=0, link-refcount=1, last-ping-sent=0, last-ok-ping-reply=315, last-ping-reply=315, down-after-milliseconds=5000, info-refresh=9270, role-reported=slave, role-reported-time=1414893, master-link-down-time=0, master-link-status=ok, master-host=192.168.138.150, master-port=7003, slave-priority=100, slave-repl-offset=299235, replica-announced=1}, {name=192.168.138.150:7002, ip=192.168.138.150, port=7002, runid=436e561915edc0469d1b381b7efdbf121042246f, flags=slave, link-pending-commands=0, link-refcount=1, last-ping-sent=0, last-ok-ping-reply=898, last-ping-reply=898, down-after-milliseconds=5000, info-refresh=9271, role-reported=slave, role-reported-time=1414894, master-link-down-time=0, master-link-status=ok, master-host=192.168.138.150, master-port=7003, slave-priority=100, slave-repl-offset=299235, replica-announced=1}], error='null'], commandType=io.lettuce.core.protocol.Command], empty stack: true

    //连接全部主从节点
    //Trying to get a Redis connection for: RedisURI [host='192.168.138.150', port=7003]
    //Trying to get a Redis connection for: RedisURI [host='192.168.138.150', port=7001]
    //Trying to get a Redis connection for: RedisURI [host='192.168.138.150', port=7002]

    //从从节点7002读
    //[channel=0xba18e6f7, /192.168.138.1:3822 -> /192.168.138.150:7002, epid=0x8] write() writeAndFlush command AsyncCommand [type=GET, output=ValueOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]

    //往主节点7003写
    //[channel=0x5a23f7c3, /192.168.138.1:3823 -> /192.168.138.150:7003, epid=0xa] write() writeAndFlush command AsyncCommand [type=SET, output=StatusOutput [output=null, error='null'], commandType=io.lettuce.core.protocol.Command]

    //主节点下线后,哨兵发现后,进行了故障转移主从切换,新的主节点是7002
    //Decoded SubscriptionCommand [type=SENTINEL, output=MapOutput [output={name=mymaster, ip=192.168.138.150, port=7002, runid=436e561915edc0469d1b381b7efdbf121042246f, flags=master, link-pending-commands=0, link-refcount=1, last-ping-sent=0, last-ok-ping-reply=37, last-ping-reply=37, down-after-milliseconds=5000, info-refresh=4449, role-reported=master, role-reported-time=166071, config-epoch=2, num-slaves=2, num-other-sentinels=2, quorum=2, failover-timeout=60000, parallel-syncs=1}, error='null'], commandType=io.lettuce.core.protocol.Command], empty stack: true
}
